﻿using ConnectDatabase;
using Database;
using Galileo;
using IBE;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using DevExpress.Web.ASPxEditors;
using IBE.LccWS;

namespace Web
{
    public partial class Result : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                if (!string.IsNullOrEmpty(Request.QueryString["SearchCondition"]))
                {
                    List<FareData> listData = new List<FareData>();
                    if (Session[Request.QueryString["SearchCondition"]] != null)
                    {
                        listData = (List<FareData>)Session[Request.QueryString["SearchCondition"]];
                        if (listData.Count == 0)
                        {
                            string responseFile = SearchFlight();
                            listData = GetListFareData(responseFile);
                            Session[Request.QueryString["SearchCondition"]] = listData;
                        }
                    }
                    else
                    {
                        string responseFile = SearchFlight();
                        listData = GetListFareData(responseFile);
                        Session[Request.QueryString["SearchCondition"]] = listData;
                    }

                    if (listData != null && listData.Count > 0)
                    {
                        InitAirlineFilter(listData);
                        InitTrackBarPrice(listData);
                        InitTrackBarFlightTime(listData);
                        InitClassFilter(listData);
                        FillData(listData);
                    }
                    else
                    {
                        Response.Redirect("~/Error.aspx", false);
                    }
                }
            }
        }

        protected tblFlightSearchArchive GetSearchConditionFromSession()
        {
            tblFlightSearchArchive obj = null;
            try
            {
                Common utility = new Common();

                if (!string.IsNullOrEmpty(Request.QueryString["SearchCondition"]))
                {
                    string searchCondition = Request.QueryString["SearchCondition"];
                    obj = new tblFlightSearchArchive();

                    if (Session[searchCondition + "Departure"] != null)
                    {
                        obj.DepartureAirportCode = Session[searchCondition + "Departure"].ToString();
                    }
                    else
                    {
                        return null;
                    }

                    if (Session[searchCondition + "Destination"] != null)
                    {
                        obj.DestinationAirportCode = Session[searchCondition + "Destination"].ToString();
                    }
                    else
                    {
                        return null;
                    }

                    if (Session[searchCondition + "DepartureDate"] != null)
                    {
                        obj.DepartureDate = utility.GetDateFormat(Session[searchCondition + "DepartureDate"].ToString(), "dd/MM/yyyy");
                    }
                    else
                    {
                        return null;
                    }

                    if (Session[searchCondition + "ReturnDate"] != null)
                    {
                        obj.ReturnDate = utility.GetDateFormat(Session[searchCondition + "ReturnDate"].ToString(), "dd/MM/yyyy");
                    }
                    else
                    {
                        return null;
                    }

                    if (Session[searchCondition + "Adt"] != null)
                    {
                        obj.Adult = Convert.ToInt16(Session[searchCondition + "Adt"].ToString());
                    }
                    else
                    {
                        return null;
                    }

                    if (Session[searchCondition + "Chd"] != null)
                    {
                        obj.Children = Convert.ToInt16(Session[searchCondition + "Chd"].ToString());
                    }
                    else
                    {
                        return null;
                    }

                    if (Session[searchCondition + "Inf"] != null)
                    {
                        obj.Infant = Convert.ToInt16(Session[searchCondition + "Inf"].ToString());
                    }
                    else
                    {
                        return null;
                    }

                    if (Session[searchCondition + "ItineraryType"] != null)
                    {
                        obj.ItineraryType = Convert.ToBoolean(Session[searchCondition + "ItineraryType"].ToString());
                    }
                    else
                    {
                        return null;
                    }

                    obj.Youth = 0;
                    obj.Senior = 0;
                }
            }
            catch
            {
                Response.Redirect("~/Error.aspx", false);
            }
            return obj;
        }

        protected tblFlightSearchArchive GetExistedSearchWithIn10Minutes(tblFlightSearchArchive newSearch)
        {
            tblFlightSearchArchive obj = new FlightSearchArchiveDB().GetExistedSearch(newSearch);
            if (obj != null)
            {
                double difference = DateTime.Now.Subtract(obj.Date.Value).TotalMinutes;
                if (difference > 10)
                {
                    obj = null;
                }
            }

            return obj;
        }

        protected string SearchFlight()
        {
            string responseFile = "";
            tblFlightSearchArchive newSearch = GetSearchConditionFromSession(); //Lấy đối tượng tblSearchArchive từ Session
            if (newSearch != null)
            {
                tblFlightSearchArchive existedSearch = GetExistedSearchWithIn10Minutes(newSearch); //Kiểm tra sự tồn tại của tìm kiếm đồng dạng trước đó 10 phút
                if (existedSearch != null)
                {
                    //Nếu đã tồn tại một tìm kiếm đồng dạng trong vòng 10 phút thì lôi nó ra
                    responseFile = existedSearch.Result;
                    RequestLCCFlight(existedSearch);
                    hdhSearchArchiveId.Value = existedSearch.Id.ToString();
                }
                else
                {
                    //Nếu không tồn tại một tìm kiếm đồng dạng trong vòng 10 phút thì thực hiện tìm kiếm mới
                    Thread threadGDS = null;
                    threadGDS = new Thread(() => { responseFile = RequestGDSFlight(newSearch); });
                    threadGDS.Start();

                    Thread threadLCC = null;
                    threadLCC = new Thread(() => { RequestLCCFlight(newSearch); });
                    threadLCC.Start();

                    if (threadGDS != null) threadGDS.Join();
                    if (threadLCC != null) threadLCC.Join();

                    Session[Request.QueryString["SearchCondition"]] = null;
                }
            }
            else
            {
                Response.Redirect("~/Error.aspx", false);
            }
            return responseFile;
        }

        protected List<FareData> GetListFareData(string fileName)
        {
            List<FareData> listData = new List<FareData>();
            try
            {
                #region GDS
                FileInfo file = new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "/Response/" + fileName);
                if (file != null && file.Exists)
                {
                    //Nếu tồn tại file XmlResponse thì bóc tách
                    XmlDocument xml = new XmlDocument();
                    try
                    {
                        xml.Load(AppDomain.CurrentDomain.BaseDirectory + "/Response/" + fileName);
                    }
                    catch
                    {

                    }
                    GDSParser parser = new GDSParser();
                    listData = RemoveLCCFromGDS(parser.FilterData(parser.GetFareData(xml)));
                }
                else
                {
                    //Nếu không tồn tại file XmlResponse thì tiến hành Request tìm kiếm mới
                    tblFlightSearchArchive newSearch = GetSearchConditionFromSession();
                    if (newSearch != null)
                    {
                        string responseFile = RequestGDSFlight(newSearch);
                        if (responseFile != "")
                        {
                            Session[Request.QueryString["SearchCondition"]] = null;
                            XmlDocument xml = new XmlDocument();
                            try
                            {
                                xml.Load(AppDomain.CurrentDomain.BaseDirectory + "/Response/" + responseFile);
                            }
                            catch
                            {

                            }
                            GDSParser parser = new GDSParser();
                            listData = parser.GetFareData(xml);
                        }
                    }
                }
                #endregion

                #region LCC
                if (Session[Request.QueryString["SearchCondition"] + "Lcc"] != null)
                {
                    List<FareData> listLccData = new List<FareData>();
                    List<FlightData> lccResponse = (List<FlightData>)Session[Request.QueryString["SearchCondition"] + "Lcc"];
                    LowcostParser service = new LowcostParser();
                    listLccData = service.GetLowcostFareData(lccResponse);

                    tblFlightSearchArchive search = GetSearchConditionFromSession();

                     foreach (FareData item in listLccData)
                     {
                         if (!search.ItineraryType.Value)
                         {
                             //Round trip
                             if (item.ListDepartureFlight.Count > 0 && item.ListReturnFlight != null && item.ListReturnFlight.Count > 0)
                             {
                                 listData.Add(item);
                             }
                         }
                         else
                         {
                             //One way
                             if (item.ListDepartureFlight.Count > 0)
                             {
                                 listData.Add(item);
                             }
                         }
                     }
                }
                #endregion

                //Re-index fare data ID
                int fareDataId = 0;
                for (int i = 0; i < listData.Count; i++)
                {
                    listData[i].FareDataId = fareDataId;
                    for (int j = 0; j < listData[i].ListDepartureFlight.Count; j++)
                    {
                        listData[i].ListDepartureFlight[j].FareDataId = fareDataId;
                    }

                    if (listData[i].ListReturnFlight != null)
                    {
                        for (int j = 0; j < listData[i].ListReturnFlight.Count; j++)
                        {
                            listData[i].ListReturnFlight[j].FareDataId = fareDataId;
                        }
                    }
                    fareDataId++;
                }

                Session[Request.QueryString["SearchCondition"]] = listData;
            }
            catch
            {
                Response.Redirect("~/Error.aspx", false);
            }
            return listData;
        }

        protected List<FareData> RemoveLCCFromGDS(List<FareData> listData)
        {
            List<FareData> newList = new List<FareData>();
            try
            {
                foreach (FareData item in listData)
                {
                    newList.Add(item.ShallowCopy());
                }

                foreach (FareData fare in newList)
                {
                    #region Departure
                    var filtered = from a in fare.ListDepartureFlight where !a.AirlineDetail.Code.Equals("VN") select a;
                    fare.ListDepartureFlight = filtered.ToList();

                    filtered = from a in fare.ListDepartureFlight where !a.AirlineDetail.Code.Equals("VJ") select a;
                    fare.ListDepartureFlight = filtered.ToList();

                    filtered = from a in fare.ListDepartureFlight where !a.AirlineDetail.Code.Equals("JQ") select a;
                    fare.ListDepartureFlight = filtered.ToList();

                    filtered = from a in fare.ListDepartureFlight where !a.AirlineDetail.Code.Equals("BL") select a;
                    fare.ListDepartureFlight = filtered.ToList();

                    filtered = from a in fare.ListDepartureFlight where !a.AirlineDetail.Code.Equals("TR") select a;
                    fare.ListDepartureFlight = filtered.ToList();

                    filtered = from a in fare.ListDepartureFlight where !a.AirlineDetail.Code.Equals("AK") select a;
                    fare.ListDepartureFlight = filtered.ToList();

                    #endregion

                    #region Return
                    if (fare.ListReturnFlight != null)
                    {
                        filtered = from a in fare.ListReturnFlight where !a.AirlineDetail.Code.Equals("VN") select a;
                        fare.ListReturnFlight = filtered.ToList();

                        filtered = from a in fare.ListReturnFlight where !a.AirlineDetail.Code.Equals("VJ") select a;
                        fare.ListReturnFlight = filtered.ToList();

                        filtered = from a in fare.ListReturnFlight where !a.AirlineDetail.Code.Equals("JQ") select a;
                        fare.ListReturnFlight = filtered.ToList();

                        filtered = from a in fare.ListReturnFlight where !a.AirlineDetail.Code.Equals("BL") select a;
                        fare.ListReturnFlight = filtered.ToList();

                        filtered = from a in fare.ListReturnFlight where !a.AirlineDetail.Code.Equals("TR") select a;
                        fare.ListReturnFlight = filtered.ToList();

                        filtered = from a in fare.ListReturnFlight where !a.AirlineDetail.Code.Equals("AK") select a;
                        fare.ListReturnFlight = filtered.ToList();
                    }
                    
                    #endregion
                }

                newList = (from a in newList
                           where a.ListDepartureFlight.Count > 0 && ((a.HasReturn) ? a.ListReturnFlight.Count > 0 : true)
                           select a).ToList();
            }
            catch
            {
                return listData;
            }

            return newList;
        }

        protected bool DetectVNFare(bool HasReturn, string PlatingCarrier, string IBE, string StartPointCountry, string EndPointCountry)
        {
            bool found = false;

            //if (HasReturn)
            //{
                if (PlatingCarrier == "VN" && IBE == "lowcost" && (StartPointCountry != EndPointCountry))
                {
                    found = true;
                }
            //}

            return found;
        }

        protected string RequestGDSFlight(tblFlightSearchArchive searchCondition)
        {
            //Hàm này thực hiện request tìm kiếm từ GDS và lưu XML response vào file
            string responseFile = "";
            try
            {
                tblGeoAirport departure = new GeoAirportDB().GetByKey(searchCondition.DepartureAirportCode);
                tblGeoAirport destination = new GeoAirportDB().GetByKey(searchCondition.DestinationAirportCode);
                if (departure != null && destination != null)
                {
                    if (departure.tblGeoCity.tblGeoCountry.Code != "VN" || destination.tblGeoCity.tblGeoCountry.Code != "VN")
                    {
                        //Chỉ search GDS với chuyến quốc tế
                        GDSParser parser = new GDSParser();
                        responseFile = searchCondition.ItineraryType.Value ? parser.GenerateResponseSearchKey(searchCondition, true) : parser.GenerateResponseSearchKey(searchCondition, false);

                        XmlDocument xmlResponse = new XmlDocument();
                        GalileoConnection conn = new GalileoConnection();

                        string default_api = ConfigurationManager.AppSettings["default_api"].ToString();
                        string hcm_pcc = ConfigurationManager.AppSettings["hcm_pcc"].ToString();
                        string hcm_name = ConfigurationManager.AppSettings["hcm_name"].ToString();

                        string xmlRequest = searchCondition.ItineraryType.Value ? parser.GenerateXmlRequest(searchCondition, true) : parser.GenerateXmlRequest(searchCondition, false);

                        string strResponse = conn.SubmitXml(xmlRequest, default_api, hcm_pcc, hcm_name);
                        if (strResponse != "")
                        {
                            try
                            {
                                xmlResponse.LoadXml(strResponse);
                            }
                            catch (Exception)
                            {

                            }
                        }

                        //Save to Xml files
                        string appPath = AppDomain.CurrentDomain.BaseDirectory;
                        FileInfo fileInfo = new FileInfo(appPath + "/Response/" + responseFile);
                        if (fileInfo != null)
                        {
                            File.Delete(appPath + "/Response/" + responseFile);
                        }

                        Common.SaveFile(appPath + "/Response/" + responseFile, xmlResponse.InnerXml);

                        //Save this search
                        searchCondition.Date = DateTime.Now;
                        searchCondition.Result = responseFile;
                        if (Session["UserID"] != null)
                        {
                            searchCondition.AccountId = Convert.ToInt32(Session["UserID"]);
                        }
                        hdhSearchArchiveId.Value = new FlightSearchArchiveDB().Save(searchCondition).ToString();
                    }
                }
            }
            catch
            {
                return "";
            }

            return responseFile;
        }

        protected void RequestLCCFlight(tblFlightSearchArchive searchCondition)
        {
            try
            {
                LowcostParser crawler = new LowcostParser();

                int adultNum = searchCondition.Adult.Value;
                int childNum = searchCondition.Children.Value;
                int infantNum = searchCondition.Infant.Value;

                List<IBE.LccWS.LccInfo> lstLccInfo = new List<IBE.LccWS.LccInfo>();
                lstLccInfo.Add(new IBE.LccWS.LccInfo { Airline = "JQ", AllowSearch = true, Account = "", Password = "" });
                lstLccInfo.Add(new IBE.LccWS.LccInfo { Airline = "VJ", AllowSearch = true, Account = "", Password = "" });
                lstLccInfo.Add(new IBE.LccWS.LccInfo { Airline = "VN", AllowSearch = true, Account = "", Password = "" });

                List<IBE.LccWS.FlightData> lstFlights = crawler.SearchLccFlight(searchCondition.ItineraryType.Value ? 1 : 2, searchCondition.DepartureAirportCode, searchCondition.DestinationAirportCode, searchCondition.DepartureDate.Value, searchCondition.ReturnDate != null ? searchCondition.ReturnDate.Value : searchCondition.DepartureDate.Value, adultNum, childNum, infantNum, lstLccInfo);

                Session[Request.QueryString["SearchCondition"] + "Lcc"] = lstFlights;
            }
            catch
            {
                Session[Request.QueryString["SearchCondition"] + "Lcc"] = null;
            }
        }

        protected void FillData(List<FareData> listData)
        {
            List<FareData> newListData = listData;

            #region Sorting
            if (hdhSortStatus.Value == "0")
            {
                if (hdhSortValue.Value == "Price")
                {
                    newListData = listData.OrderBy(x => x.TotalFare + x.TotalFee).ToList();
                }
                else if (hdhSortValue.Value == "FlightDuration")
                {
                    newListData = listData.OrderBy(x => x.TotalDuration).ToList();
                }
                else if (hdhSortValue.Value == "DepartureTime")
                {
                    newListData = listData.OrderBy(x => x.DepartureDate).ToList();
                }
                else if (hdhSortValue.Value == "ReturnTime")
                {
                    newListData = listData.OrderBy(x => x.ReturnDate).ToList();
                }
            }
            else
            {
                if (hdhSortValue.Value == "Price")
                {
                    newListData = listData.OrderByDescending(x => x.TotalFare + x.TotalFee).ToList();
                }
                else if (hdhSortValue.Value == "FlightDuration")
                {
                    newListData = listData.OrderByDescending(x => x.TotalDuration).ToList();
                }
                else if (hdhSortValue.Value == "DepartureTime")
                {
                    newListData = listData.OrderByDescending(x => x.DepartureDate).ToList();
                }
                else if (hdhSortValue.Value == "ReturnTime")
                {
                    newListData = listData.OrderByDescending(x => x.ReturnDate).ToList();
                }
            }


            #endregion

            #region Paging
            PagedDataSource pgitems = new PagedDataSource();
            pgitems.DataSource = newListData;
            pgitems.AllowPaging = true;
            pgitems.PageSize = 10;
            int index = Convert.ToInt16(hdnPageIndex.Value);
            pgitems.CurrentPageIndex = index;
            if (pgitems.PageCount > 1)
            {
                repPages.Visible = true;
                System.Collections.ArrayList pages = new System.Collections.ArrayList();
                for (int i = 0; i < pgitems.PageCount; i++)
                {
                    pages.Add((i + 1).ToString());
                }
                repPages.DataSource = pages;
                repPages.DataBind();
            }
            else
            {
                repPages.Visible = false;
            }

            if (pgitems != null)
            {
                repFilght.DataSource = pgitems;
                repFilght.DataBind();
            }

            if (pgitems.PageCount > 1)
            {
                RepeaterItem item = repPages.Items[index];
                LinkButton link = (LinkButton)item.FindControl("btnPage");
                link.Enabled = false;
                link.CssClass = "visited";
            }
            #endregion

            if (newListData.Count > 0)
            {
                repFilght.Visible = true;
            }
            else
            {
                repFilght.Visible = false;
            }

            newListData = null;
        }

        protected void FilterFareData()
        {
            try
            {
                List<FareData> listData = new List<FareData>();
                if (Session[Request.QueryString["SearchCondition"]] != null)
                {
                    listData = (List<FareData>)Session[Request.QueryString["SearchCondition"]];
                }
                else
                {
                    string responseFile = SearchFlight();
                    listData = GetListFareData(responseFile);
                }

                List<FareData> newList = new List<FareData>();
                foreach (FareData item in listData)
                {
                    newList.Add(item.ShallowCopy());
                }

                foreach (FareData fare in newList)
                {
                    #region Departure
                    //Filter by stop points
                    var filtered = from a in fare.ListDepartureFlight
                                   where ((!ckbDirectFlight.Checked) ? a.StopNum != 0 : true)
                                    && ((!ckbOneStop.Checked) ? a.StopNum != 1 : true)
                                    && ((!ckbTwoStop.Checked) ? a.StopNum != 2 : true)
                                    && ((!ckbThreeStop.Checked) ? a.StopNum != 3 : true)
                                    && a.Duration.TotalMinutes <= (Convert.ToDouble(trackBarTotalFlightTime.Value))
                                   select a;
                    fare.ListDepartureFlight = filtered.ToList();

                    //Filter by airlines
                    for (int i = 0; i < ckbListAirline.Items.Count; i++)
                    {
                        if (!ckbListAirline.Items[i].Selected)
                        {
                            filtered = from a in fare.ListDepartureFlight
                                       where !a.AirlineDetail.Code.Equals(ckbListAirline.Items[i].Value)
                                       select a;
                            fare.ListDepartureFlight = filtered.ToList();
                        }
                    }

                    //Filter by class
                    if (!ckbAllClass.Checked)
                    {
                        List<Flight> tempListFlt = new List<Flight>();
                        foreach (Flight flt in fare.ListDepartureFlight)
                        {
                            Flight tempFlt = flt.ShallowCopy();
                            for (int i = 0; i < ckbListClass.Items.Count; i++)
                            {
                                if (!ckbListClass.Items[i].Selected)
                                {
                                    tempFlt.ListAvailFlt = tempFlt.ListAvailFlt.Where(a => !a.Class.Equals(ckbListClass.Items[i].Value)).ToList();
                                }
                            }
                            if (tempFlt.ListAvailFlt.Count > 0)
                            {
                                tempListFlt.Add(tempFlt);
                            }
                        }

                        fare.ListDepartureFlight = tempListFlt;
                    }
                    #endregion

                    #region Return
                    if (fare.HasReturn)
                    {
                        //Filter by stop points
                        filtered = from a in fare.ListReturnFlight
                                   where ((!ckbDirectFlight.Checked) ? a.StopNum != 0 : true)
                                    && ((!ckbOneStop.Checked) ? a.StopNum != 1 : true)
                                    && ((!ckbTwoStop.Checked) ? a.StopNum != 2 : true)
                                    && ((!ckbThreeStop.Checked) ? a.StopNum != 3 : true)
                                    && a.Duration.TotalMinutes <= (Convert.ToDouble(trackBarTotalFlightTime.Value))
                                   select a;
                        fare.ListReturnFlight = filtered.ToList();

                        //Filter by airlines
                        for (int i = 0; i < ckbListAirline.Items.Count; i++)
                        {
                            if (!ckbListAirline.Items[i].Selected)
                            {
                                filtered = from a in fare.ListReturnFlight
                                           where !a.AirlineDetail.Code.Equals(ckbListAirline.Items[i].Value)
                                           select a;
                                fare.ListReturnFlight = filtered.ToList();
                            }
                        }

                        //Filter by class
                        if (!ckbAllClass.Checked)
                        {
                            List<Flight> tempListFlt = new List<Flight>();
                            foreach (Flight flt in fare.ListReturnFlight)
                            {
                                Flight tempFlt = flt.ShallowCopy();
                                for (int i = 0; i < ckbListClass.Items.Count; i++)
                                {
                                    if (!ckbListClass.Items[i].Selected)
                                    {
                                        tempFlt.ListAvailFlt = tempFlt.ListAvailFlt.Where(a => !a.Class.Equals(ckbListClass.Items[i].Value)).ToList();
                                    }
                                }
                                if (tempFlt.ListAvailFlt.Count > 0)
                                {
                                    tempListFlt.Add(tempFlt);
                                }
                            }

                            fare.ListReturnFlight = tempListFlt;
                        }
                    }
                    #endregion
                }

                newList = (from a in newList
                           where a.ListDepartureFlight.Count > 0 && ((a.HasReturn) ? a.ListReturnFlight.Count > 0 : true)
                           && (a.TotalFare + a.TotalFee) <= Convert.ToDouble(trackBarPrice.Value)
                           select a).ToList();

                if (newList.Count <= 10)
                {
                    hdnPageIndex.Value = "0";
                }
                else
                {
                    int numberOfPages = (newList.Count / 10) + (newList.Count % 10 == 0 ? 0 : 1);
                    int index = Convert.ToInt16(hdnPageIndex.Value);
                    if (index + 1 > numberOfPages)
                    {
                        hdnPageIndex.Value = "0";
                    }
                }

                FillData(newList);
                //RadAjaxManager1.ResponseScripts.Add("ScrollToControl()");
            }
            catch
            {
                Response.Redirect("~/Error.aspx", false);
            }
        }

        protected void repFilght_ItemCommand(object source, RepeaterCommandEventArgs e)
        {
            try
            {
                if (e.CommandName.Equals("Continue"))
                {
                    string id = e.CommandArgument.ToString();
                    string url = "";

                    string FareInputControlName = "FareItem" + id;
                    string DepartureInputControlName = "DepartureFlightValue" + id;
                    string ReturnInputControlName = "ReturnFlightValue" + id;
                    string HasReturnInputControlName = "HasReturn" + id;

                    string FareDataId = Request.Form[FareInputControlName].ToString();
                    string DepartureId = Request.Form[DepartureInputControlName].ToString();
                    string ReturnId = Request.Form[ReturnInputControlName].ToString();

                    string SelectedValue = FareDataId + "-" + DepartureId + "-" + ReturnId;

                    url = "~/Book.aspx?&Search=" + Request.QueryString["SearchCondition"] + "&SelectedValue=" + SelectedValue;

                    Session[Request.QueryString["SearchCondition"] + SelectedValue + "FareDataId"] = FareDataId;
                    Session[Request.QueryString["SearchCondition"] + SelectedValue + "DepartureId"] = DepartureId;
                    Session[Request.QueryString["SearchCondition"] + SelectedValue + "ReturnId"] = ReturnId;

                    List<FareData> listData = (List<FareData>)Session[Request.QueryString["SearchCondition"]];
                    if (listData == null)
                    {
                        //Nếu Session == null thì lấy listData từ file
                        string responseFile = SearchFlight();
                        listData = GetListFareData(responseFile);
                    }
                    FareData temp = listData.FirstOrDefault(a => a.FareDataId == Convert.ToInt32(FareDataId)).ShallowCopy();

                    LowcostParser parser = new LowcostParser();
                    #region Submit lấy giá thật trên VN LCC
                    try
                    {
                        if (DetectVNFare(temp.HasReturn, temp.PlatingCarrier, temp.IBE, temp.ListDepartureFlight[Convert.ToInt32(DepartureId)].StartPointCity.tblGeoCountry.Code, temp.ListDepartureFlight[Convert.ToInt32(DepartureId)].EndPointCity.tblGeoCountry.Code))
                        {
                            string session = temp.SessionId;
                            string departureSelectValue = temp.ListDepartureFlight[Convert.ToInt32(DepartureId)].SelectValue;
                            string returnSelectValue = "";
                            if (temp.HasReturn)
                            {
                                returnSelectValue = temp.ListReturnFlight[Convert.ToInt32(ReturnId)].SelectValue;
                            }

                            FlightFare fareVN = parser.GetTotalPriceVN(temp.HasReturn ? 2 : 1, departureSelectValue, returnSelectValue, session);

                            if (fareVN != null)
                            {
                                temp.FareAdult = Common.MoneyExchange(fareVN.PriceAdult + fareVN.TaxAdult + fareVN.FeeAdult, "VND", temp.CurrencyCode);
                                temp.FareChild = fareVN.Child > 0 ? Common.MoneyExchange(fareVN.PriceChild + fareVN.TaxChild + fareVN.FeeChild, "VND", temp.CurrencyCode) : 0;
                                temp.FareInfant = fareVN.Infant > 0 ? Common.MoneyExchange(fareVN.PriceInfant + fareVN.TaxInfant + fareVN.FeeInfant, "VND", temp.CurrencyCode) : 0;

                                temp.FeeAdult = parser.ConvertStringToDouble(ConfigurationManager.AppSettings["defaul_fee_adt_rt"].ToString()) * temp.FareAdult / 100;
                                temp.FeeChild = parser.ConvertStringToDouble(ConfigurationManager.AppSettings["defaul_fee_chd_rt"].ToString()) * temp.FareChild / 100;
                                temp.FeeInfant = parser.ConvertStringToDouble(ConfigurationManager.AppSettings["defaul_fee_inf_rt"].ToString()) * temp.FareInfant / 100;

                                temp.TotalFee = temp.TotalAdult * temp.FeeAdult + temp.TotalChild * temp.FeeChild + temp.TotalInfant * temp.FeeInfant;
                                temp.TotalFare = Common.MoneyExchange(fareVN.TotalPrice, "VND", temp.CurrencyCode);
                            }
                        }
                    }
                    catch
                    {

                    }
                    #endregion

                    #region Baggage
                    try
                    {
                        for (int i = 0; i < Session.Count; i++)
                        {
                            string key = Session.Keys[i];
                            if (key.StartsWith("Baggage"))
                            {
                                Session[i] = null;
                            }
                        }

                        if ((temp.PlatingCarrier == "JQ" || temp.PlatingCarrier == "VJ") && temp.IBE == "lowcost")
                        {
                            if (temp.HasReturn)
                            {
                                string departureFlightInfo = temp.ListDepartureFlight[Convert.ToInt32(DepartureId)].SelectValue;
                                string returnFlightInfo = temp.ListReturnFlight[Convert.ToInt32(ReturnId)].SelectValue;
                                int segmentDepart = temp.ListDepartureFlight[Convert.ToInt32(DepartureId)].ListAvailFlt.Count;
                                int segmentReturn = temp.ListReturnFlight[Convert.ToInt32(ReturnId)].ListAvailFlt.Count;
                                bool isDomestic = (temp.ListDepartureFlight[Convert.ToInt32(DepartureId)].StartPointAirport.tblGeoCity.CountryCode == "VN" && temp.ListDepartureFlight[Convert.ToInt32(DepartureId)].EndPointAirport.tblGeoCity.CountryCode == "VN") ? true : false;

                                BaggageInfo baggage = parser.GetBaggages(temp.PlatingCarrier, 2, departureFlightInfo, returnFlightInfo, temp.SessionId, isDomestic, segmentDepart, segmentReturn);
                                if (baggage != null)
                                {
                                    if (baggage.BaggageDepart != null && baggage.BaggageDepart.Length > 0)
                                    {
                                        Session[Request.QueryString["SearchCondition"] + SelectedValue + "-Baggage-Depart"] = baggage.BaggageDepart.ToList();
                                    }

                                    if (baggage.BaggageReturn != null && baggage.BaggageReturn.Length > 0)
                                    {
                                        Session[Request.QueryString["SearchCondition"] + SelectedValue + "-Baggage-Return"] = baggage.BaggageDepart.ToList();
                                    }
                                }
                            }
                            else
                            {
                                string departureFlightInfo = temp.ListDepartureFlight[Convert.ToInt32(DepartureId)].SelectValue;
                                int segmentDepart = temp.ListDepartureFlight[Convert.ToInt32(DepartureId)].ListAvailFlt.Count;
                                bool isDomestic = (temp.ListDepartureFlight[Convert.ToInt32(DepartureId)].StartPointAirport.tblGeoCity.CountryCode == "VN" && temp.ListDepartureFlight[Convert.ToInt32(DepartureId)].EndPointAirport.tblGeoCity.CountryCode == "VN") ? true : false;

                                BaggageInfo baggage = parser.GetBaggages(temp.PlatingCarrier, 1, departureFlightInfo, "", temp.SessionId, isDomestic, segmentDepart, 0);
                                if (baggage != null)
                                {
                                    if (baggage.BaggageDepart != null && baggage.BaggageDepart.Length > 0)
                                    {
                                        Session[Request.QueryString["SearchCondition"] + SelectedValue + "-Baggage-Depart"] = baggage.BaggageDepart.ToList();
                                    }
                                }
                            }

                            
                        }
                    }
                    catch
                    {

                    }
                    #endregion

                    Session[Request.QueryString["SearchCondition"] + SelectedValue] = temp;
                    Response.Redirect(url, false);
                }
            }
            catch
            {
                
            }
        }

        protected void repPages_ItemCommand(object source, RepeaterCommandEventArgs e)
        {
            hdnPageIndex.Value = (Convert.ToInt32(e.CommandArgument) - 1).ToString();
            FilterFareData();
        }

        #region Sorting
        protected void lnkSortPrice_Click(object sender, EventArgs e)
        {
            SortingFlight(lnkSortPrice, "Price");
        }

        protected void lnkSortFlightDuration_Click(object sender, EventArgs e)
        {
            SortingFlight(lnkSortFlightDuration, "FlightDuration");
        }

        protected void lnkSortDepartureTime_Click(object sender, EventArgs e)
        {
            SortingFlight(lnkSortDepartureTime, "DepartureTime");
        }

        protected void lnkSortReturnTime_Click(object sender, EventArgs e)
        {
            SortingFlight(lnkSortReturnTime, "ReturnTime");
        }

        protected void ResetSortStyle()
        {
            lnkSortPrice.CssClass = "SortLink";
            lnkSortFlightDuration.CssClass = "SortLink";
            lnkSortDepartureTime.CssClass = "SortLink";
            lnkSortReturnTime.CssClass = "SortLink";
        }

        protected void SetSortStyle(LinkButton control, string cssClass)
        {
            ResetSortStyle();
            control.CssClass = "SortLink " + cssClass;
        }

        protected void SortingFlight(LinkButton control, string comparison)
        {
            if (hdhSortStatus.Value == "1")
            {
                hdhSortValue.Value = comparison;
                hdhSortStatus.Value = "0";
                SetSortStyle(control, "Ascending");
            }
            else
            {
                hdhSortValue.Value = comparison;
                hdhSortStatus.Value = "1";
                SetSortStyle(control, "Descending");
            }

            FilterFareData();
        }
        #endregion

        #region Filter
        protected void ckbDirectFlight_CheckedChanged(object sender, EventArgs e)
        {
            FilterFareData();
        }

        protected void ckbOneStop_CheckedChanged(object sender, EventArgs e)
        {
            FilterFareData();
        }

        protected void ckbTwoStop_CheckedChanged(object sender, EventArgs e)
        {
            FilterFareData();
        }

        protected void ckbThreeStop_CheckedChanged(object sender, EventArgs e)
        {
            FilterFareData();
        }

        protected void InitAirlineFilter(List<FareData> listData)
        {
            var obj = from a in listData
                      from b in a.ListDepartureFlight
                      group b.AirlineDetail by b.AirlineDetail.Code into g
                      select g.First();
            List<tblAirline> listAirline = obj.ToList();

            try
            {
                obj = from a in listData
                      from b in a.ListReturnFlight
                      group b.AirlineDetail by b.AirlineDetail.Code into g
                      select g.First();

                List<tblAirline> listAirlineReturn = obj.ToList();
                foreach (tblAirline item in listAirlineReturn)
                {
                    listAirline.Add(item);
                }

                obj = from a in listAirline
                      group a by a.Code into g
                      select g.First();
                listAirline = obj.ToList();
            }
            catch
            {
                obj = from a in listAirline
                      group a by a.Code into g
                      select g.First();
                listAirline = obj.ToList();
            }

            ckbListAirline.Items.Clear();
            foreach (tblAirline airline in listAirline)
            {
                ListItem item = new ListItem();
                item.Value = airline.Code;
                item.Text = airline.Name_Vi;
                item.Selected = true;
                ckbListAirline.Items.Add(item);
            }
        }

        protected void InitTrackBarPrice(List<FareData> listData)
        {
            try
            {
                decimal maxPrice = Convert.ToDecimal((from a in listData
                                                      select a.TotalFare + a.TotalFee).Max());
                decimal minPrice = Convert.ToDecimal((from a in listData
                                                      select a.TotalFare + a.TotalFee).Min());

                if (maxPrice > 1000000)
                {
                    trackBarPrice.MaxValue = maxPrice;
                    trackBarPrice.MinValue = minPrice;
                    trackBarPrice.Step = 200000;
                    trackBarPrice.Value = maxPrice;

                    string currency = "M " + ConfigurationManager.AppSettings["default_currency"].ToString();

                    minPrice = minPrice / 1000000;
                    maxPrice = maxPrice / 1000000;

                    lblPrice.Text = minPrice.ToString("#,0.##") + currency + " - " + maxPrice.ToString("#,0.##") + currency;
                }
                else
                {
                    trackBarPrice.MaxValue = maxPrice;
                    trackBarPrice.MinValue = minPrice;
                    trackBarPrice.Step = 20;
                    trackBarPrice.Value = maxPrice;

                    string currency = ConfigurationManager.AppSettings["default_currency"].ToString();

                    lblPrice.Text = minPrice.ToString("#,0.##") + currency + " - " + maxPrice.ToString("#,0.##") + currency;
                }
            }
            catch
            {
                //Nothing to do
            }
        }

        protected void InitTrackBarFlightTime(List<FareData> listData)
        {
            try
            {
                double maxDepartureDuration = (from a in listData
                                               where a.ListDepartureFlight != null
                                               from b in a.ListDepartureFlight
                                               select b.Duration.TotalMinutes).Max();
                double minDepartureDuration = (from a in listData
                                               where a.ListDepartureFlight != null
                                               from b in a.ListDepartureFlight
                                               select b.Duration.TotalMinutes).Min();

                double maxReturnDuration = maxDepartureDuration;
                double minReturnDuration = minDepartureDuration;

                if (listData[0].HasReturn)
                {
                    maxReturnDuration = (from a in listData
                                         where a.ListReturnFlight != null
                                         from b in a.ListReturnFlight
                                         select b.Duration.TotalMinutes).Max();
                    minReturnDuration = (from a in listData
                                         where a.ListReturnFlight != null
                                         from b in a.ListReturnFlight
                                         select b.Duration.TotalMinutes).Min();
                }

                trackBarTotalFlightTime.MaxValue = Convert.ToInt32(maxDepartureDuration > maxReturnDuration ? maxDepartureDuration : maxReturnDuration);
                trackBarTotalFlightTime.MinValue = Convert.ToInt32(minDepartureDuration < minReturnDuration ? minDepartureDuration : minReturnDuration);
                trackBarTotalFlightTime.Step = 10;
                trackBarTotalFlightTime.Value = Convert.ToInt32(maxDepartureDuration > maxReturnDuration ? maxDepartureDuration : maxReturnDuration);
                TimeSpan minTime = TimeSpan.FromMinutes(Convert.ToDouble(trackBarTotalFlightTime.MinValue));
                TimeSpan time = TimeSpan.FromMinutes(Convert.ToDouble(trackBarTotalFlightTime.Value));
                lblTotalFlightTime.Text = string.Format("{0}h {1}m", minTime.Days * 24 + minTime.Hours, minTime.Minutes) + " - " + string.Format("{0}h {1}m", time.Days * 24 + time.Hours, time.Minutes);
            }
            catch
            {
                //Nothing to do
            }
        }

        protected void InitClassFilter(List<FareData> listData)
        {
            var obj = from a in listData
                      from b in a.ListDepartureFlight
                      from c in b.ListAvailFlt
                      group c.Class by c.Class into g
                      select g.First();
            List<string> listClass = obj.ToList();

            try
            {
                obj = from a in listData
                      from b in a.ListReturnFlight
                      from c in b.ListAvailFlt
                      group c.Class by c.Class into g
                      select g.First();

                List<string> listClassReturn = obj.ToList();
                foreach (string item in listClassReturn)
                {
                    listClass.Add(item);
                }

                obj = from a in listClass
                      group a by a into g
                      select g.First();
                listClass = obj.ToList();
            }
            catch
            {
                obj = from a in listClass
                      group a by a into g
                      select g.First();
                listClass = obj.ToList();
            }

            listClass = listClass.OrderBy(a => a).ToList();

            ckbListClass.Items.Clear();
            foreach (string item in listClass)
            {
                ListItem items = new ListItem();
                items.Value = item;
                items.Text = item;
                items.Selected = false;
                ckbListClass.Items.Add(items);
            }
        }

        protected void ckbListAirline_SelectedIndexChanged(object sender, EventArgs e)
        {
            FilterFareData();
        }

        protected void ckbListClass_SelectedIndexChanged(object sender, EventArgs e)
        {
            ckbAllClass.Checked = false;
            FilterFareData();
        }

        protected void ckbAllClass_CheckedChanged(object sender, EventArgs e)
        {
            if (ckbAllClass.Checked)
            {
                for (int i = 0; i < ckbListClass.Items.Count; i++)
                {
                    ckbListClass.Items[i].Selected = false;
                }
            }
            FilterFareData();
        }

        protected void trackBarPrice_ValueChanged(object sender, EventArgs e)
        {
            try
            {
                if (trackBarPrice.MaxValue > 1000000)
                {
                    string currency = "M " + ConfigurationManager.AppSettings["default_currency"].ToString();

                    decimal minPrice = trackBarPrice.MinValue / 1000000;
                    decimal price = Convert.ToDecimal(trackBarPrice.Value) / 1000000;

                    lblPrice.Text = minPrice.ToString("#,0.##") + currency + " - " + price.ToString("#,0.##") + currency;
                }
                else
                {
                    decimal minPrice = trackBarPrice.MinValue;
                    decimal price = Convert.ToDecimal(trackBarPrice.Value);

                    string currency = ConfigurationManager.AppSettings["default_currency"].ToString();

                    lblPrice.Text = minPrice.ToString("#,0.##") + currency + " - " + price.ToString("#,0.##") + currency;
                }

                FilterFareData();
            }
            catch
            {
                //Nothing to do
            }
        }

        protected void trackBarTotalFlightTime_ValueChanged(object sender, EventArgs e)
        {
            try
            {
                TimeSpan minTime = TimeSpan.FromMinutes(Convert.ToDouble(trackBarTotalFlightTime.MinValue));
                TimeSpan time = TimeSpan.FromMinutes(Convert.ToDouble(trackBarTotalFlightTime.Value));
                lblTotalFlightTime.Text = string.Format("{0}h {1}m", minTime.Days * 24 + minTime.Hours, minTime.Minutes) + " - " + string.Format("{0}h {1}m", time.Days * 24 + time.Hours, time.Minutes);
                FilterFareData();
            }
            catch
            {
                //Nothing to do
            }
        }
        #endregion
    }
}